package com.doris.lucene;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.Logger;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.doris.lucene.servlet.LuceneServletContextListener;

/**
 * Tika解析文档，Lucene生成索引
 * 
 * @author root
 *
 */
public class LuceneIndexer {

	private static final Logger LOGGER = Logger.getLogger(LuceneIndexer.class);
	/**
	 * 解析文档计数，解析线程结束后通知索引程序结束
	 */
	private static AtomicInteger counts = new AtomicInteger(0);
	/**
	 * 解析线程生产，索引线程消费
	 */
	private static BlockingQueue<LuceneDocument> queues = new LinkedBlockingQueue<LuceneDocument>();

	public static BlockingQueue<LuceneDocument> getQueues() {
		return queues;
	}

	public static AtomicInteger getCounts() {
		return counts;
	}

	/**
	 * 写索引
	 */
	public void index() {
		// 一个索引写进程（消费者）DocumentIndexThread，多个文档解析进程（生产者）DocumentParseThread
		IndexWriter writer = null;
		int size = -1;
		DocumentIndexThread indexThread = null;
		try {
			String directory = LuceneProperties.getIndexDir() + "/"
					+ new SimpleDateFormat(Constants.DATE_TIME_FORMAT).format(new Date());
			LuceneProperties.setLockedDir(directory);
			if (!new File(directory).exists()) {
				new File(directory).mkdirs();
			}
			FSDirectory dir = FSDirectory.open(new File(directory));
			IndexWriterConfig iwc = new IndexWriterConfig(Version.LATEST, new IKAnalyzer(true));
			iwc.setOpenMode(OpenMode.CREATE);
			writer = new IndexWriter(dir, iwc);
			indexThread = new DocumentIndexThread(writer);
			indexThread.start();

			List<String> files = new ArrayList<String>();
			List<Object> searchDirs = LuceneProperties.getSearchDirs();
			for (Object searchDir : searchDirs) {
				LOGGER.info("爬取目录：" + searchDir);
				List<String> fileGroup = new FileSearcher().search((String) searchDir);
				files.addAll(fileGroup);
				LOGGER.info("爬取文件数：" + fileGroup.size());
			}
			size = files.size();
			for (String path : files) {
				Runnable parseThread = new DocumentParseThread(path);
				LuceneServletContextListener.getPool().execute(parseThread);
			}
		} catch (IOException e1) {
			LOGGER.error("写索引失败", e1);
		} finally {
			while (size != counts.get()) {
				sleep();
			}
			counts.set(0);
			if (indexThread != null) {
				indexThread.finish();
			}
			while (!queues.isEmpty()) {
				sleep();
			}
			LuceneProperties.setLockedDir(Constants.DEFAULT_LOCKED_DIR);
		}
	}

	/**
	 * 休眠当前线程500毫秒
	 */
	private void sleep() {
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			LOGGER.error("线程被中断", e);
		}
	}

}
